package com.project.school_flate.serviceimpl.order;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.project.school_flate.dto.order.OrderTakeawayCommodityDto;
import com.project.school_flate.dto.order.OrderTakeawayDto;
import com.project.school_flate.entity.order.OrderTakeawayCommodity;
import com.project.school_flate.entity.order.OrderTakeawayCommodity;
import com.project.school_flate.entity.shop.*;
import com.project.school_flate.entity.shop.table.ShopInfoTableDef;
import com.project.school_flate.entity.table.order.OrderTakeawayCommodityTable;
import com.project.school_flate.entity.table.shop.ShopCommoditySpecsTable;
import com.project.school_flate.entity.table.shop.ShopCommoditySpecsTypeTable;
import com.project.school_flate.entity.table.shop.ShopCommodityTable;
import com.project.school_flate.entity.table.shop.ShopSaveUserTable;
import com.project.school_flate.entity.user.UserInfo;
import com.project.school_flate.mapper.order.OrderTakeawayCommodityMapper;
import com.project.school_flate.mapper.shop.*;
import com.project.school_flate.service.order.OrderTakeawayCommodityService;
import com.project.school_flate.util.PoToDTO;
import com.project.school_flate.util.Result.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  服务层实现。
 *
 * @author 马维健
 * @since 2024/1/2
 */
@Service
public class OrderTakeawayCommodityServiceImpl extends ServiceImpl<OrderTakeawayCommodityMapper, OrderTakeawayCommodity> implements OrderTakeawayCommodityService {

    @Autowired
    private OrderTakeawayCommodityMapper oOrderTakeawayCommodityMapper;

    @Autowired
    private ShopCommoditySpecsTypeMapper oShopCommoditySpecsTypeMapper;

    @Autowired
    private ShopInfoMapper oShopInfoMapper;

    @Autowired
    private ShopSaveUserMapper oShopSaveUserMapper;

    @Autowired
    private ShopCommoditySpecsMapper oShopCommoditySpecsMapper;

    @Autowired
    private ShopCommodityMapper oShopCommodityMapper;

    /**
     * 获取外卖订单商品
     * @param oOrderTakeawayCommodityDto
     * @return
     * @throws Exception
     */
    @Override
    public Result getOrderTakeawayCommodity(OrderTakeawayCommodityDto oOrderTakeawayCommodityDto) throws Exception {
        List<OrderTakeawayCommodity> oOrderTakeawayCommodityList = new ArrayList<>();
        long total = 0;
        QueryWrapper queryWrapper = new QueryWrapper();
        //判断是否传入订单ID
        if(StringUtils.isNotBlank(oOrderTakeawayCommodityDto.getOrderTakeawayId())){
            queryWrapper.where(OrderTakeawayCommodityTable.ORDER_TAKEAWAY_COMMODITY.ORDER_TAKEAWAY_ID.eq(oOrderTakeawayCommodityDto.getOrderTakeawayId()));
        }
        queryWrapper.orderBy("create_time desc");
        //是否分页
        if(oOrderTakeawayCommodityDto.getPage() != null && oOrderTakeawayCommodityDto.getLimit() != null){
            Page<OrderTakeawayCommodity> OrderTakeawayCommodityPage = oOrderTakeawayCommodityMapper.paginateWithRelations(oOrderTakeawayCommodityDto.getPage(),oOrderTakeawayCommodityDto.getLimit(),queryWrapper);
            oOrderTakeawayCommodityList = OrderTakeawayCommodityPage.getRecords();
            total = OrderTakeawayCommodityPage.getTotalRow();
        }else{
            oOrderTakeawayCommodityList = oOrderTakeawayCommodityMapper.selectListWithRelationsByQuery(queryWrapper);
            total = oOrderTakeawayCommodityList.size();
        }
        //PoToDto
        List<OrderTakeawayCommodityDto> oOrderTakeawayCommodityDtoList = (List<OrderTakeawayCommodityDto>) PoToDTO.poToDtoList(oOrderTakeawayCommodityList,new OrderTakeawayCommodityDto());
        return Result.ok(oOrderTakeawayCommodityDtoList,total);
    }

    /**
     * 添加外卖订单商品
     * @param oOrderTakeawayCommodityDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result addOrderTakeawayCommodity(OrderTakeawayCommodityDto oOrderTakeawayCommodityDto) throws Exception {
        OrderTakeawayCommodity oOrderTakeawayCommodity = new OrderTakeawayCommodity();
        PoToDTO.poToDto(oOrderTakeawayCommodityDto,oOrderTakeawayCommodity);
        if(oOrderTakeawayCommodityMapper.insert(oOrderTakeawayCommodity) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("添加外卖订单商品失败");
        }
        return Result.ok("添加外卖订单商品成功");
    }

    /**
     * 修改外卖订单商品
     * @param oOrderTakeawayCommodityDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result updateOrderTakeawayCommodity(OrderTakeawayCommodityDto oOrderTakeawayCommodityDto) throws Exception {
        OrderTakeawayCommodity oOrderTakeawayCommodity = new OrderTakeawayCommodity();
        PoToDTO.poToDto(oOrderTakeawayCommodityDto,oOrderTakeawayCommodity);
        if(oOrderTakeawayCommodityMapper.update(oOrderTakeawayCommodity) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("修改外卖订单商品失败");
        }
        return Result.ok("修改外卖订单商品成功");
    }

    /**
     * 删除外卖订单商品
     * @param oOrderTakeawayCommodityDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result deleteOrderTakeawayCommodity(OrderTakeawayCommodityDto oOrderTakeawayCommodityDto) throws Exception {
        OrderTakeawayCommodity oOrderTakeawayCommodity = new OrderTakeawayCommodity();
        PoToDTO.poToDto(oOrderTakeawayCommodityDto,oOrderTakeawayCommodity);
        if(oOrderTakeawayCommodityMapper.deleteById(oOrderTakeawayCommodity.getId()) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("删除外卖订单商品失败");
        }
        return Result.ok("删除外卖订单商品成功");
    }

    /**
     * 核算购物车外卖订单价格（客户）
     * @param oOrderTakeawayCommodityDto
     * @return
     * @throws Exception
     */
    @Override
    public Result countCarOrderIntegral(OrderTakeawayCommodityDto oOrderTakeawayCommodityDto) throws Exception {
        //获取当前登录人
        UserInfo oUserInfo = new UserInfo();
        if(StpUtil.isLogin()){
            oUserInfo = (UserInfo) StpUtil.getSession().get("userInfo");
            if(oUserInfo == null || StringUtils.isBlank(oUserInfo.getId())){
                return Result.error("请先重新登录");
            }
        }else{
            return Result.error("请先重新登录");
        }
        //获取店铺信息
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ShopInfoTableDef.SHOP_INFO.ID.eq(oOrderTakeawayCommodityDto.getCarShopId()));
        queryWrapper.where(ShopInfoTableDef.SHOP_INFO.STATE.eq(1));
        ShopInfo oShopInfo = oShopInfoMapper.selectOneByQuery(queryWrapper);
        if(oShopInfo == null){
            return Result.error("店铺不存在");
        }
        //判断店铺是否营业
        if(oShopInfo.getIsTrade() == 0){
            return Result.error("店铺已暂停营业");
        }
        //判断用户是否是此店铺的储蓄会员
        Boolean isSave = false;
        if(oShopInfo.getIsOpenSave() == 1){
            queryWrapper = new QueryWrapper();
            queryWrapper.where(ShopSaveUserTable.SHOP_SAVE_USER.USER_ID.eq(oUserInfo.getId()));
            queryWrapper.where(ShopSaveUserTable.SHOP_SAVE_USER.SHOP_ID.eq(oShopInfo.getId()));
            if(oShopSaveUserMapper.selectOneByQuery(queryWrapper) != null){
                isSave = true;
            }
        }
        //获取购物车外卖订单商品列表
        List<OrderTakeawayCommodityDto> carOrderTakeawayCommodityDtoList = oOrderTakeawayCommodityDto.getCarOrderTakeawayCommodityDtoList();
        if(CollectionUtils.isEmpty(carOrderTakeawayCommodityDtoList)){
            return Result.error("请先选择商品");
        }
        //获取查到的所有商品ID
        List<String> oShopCommodityIdList = new ArrayList<>();
        //获取查到的所有规格ID
        List<String> oShopCommoditySpecsIdList = new ArrayList<>();
        carOrderTakeawayCommodityDtoList.forEach(item->{
            oShopCommodityIdList.add(item.getCommodityId());
            if(CollectionUtil.isNotEmpty(item.getCarShopCommoditySpecsIdList())){
                oShopCommoditySpecsIdList.addAll(item.getCarShopCommoditySpecsIdList());
            }
        });
        //获取查到的所有商品信息
        queryWrapper = new QueryWrapper();
        queryWrapper.where(ShopCommodityTable.SHOP_COMMODITY.ID.in(oShopCommodityIdList));
        List<ShopCommodity> oShopCommodityList = oShopCommodityMapper.selectListByQuery(queryWrapper);
        //获取查到的所有规格信息
        List<ShopCommoditySpecs> oShopCommoditySpecsList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(oShopCommoditySpecsIdList)){
            queryWrapper = new QueryWrapper();
            queryWrapper.where(ShopCommoditySpecsTable.SHOP_COMMODITY_SPECS.ID.in(oShopCommoditySpecsIdList));
            oShopCommoditySpecsList = oShopCommoditySpecsMapper.selectListByQuery(queryWrapper);
        }
        //重组
        Map<String,ShopCommodity> oShopCommodityMap = new HashMap<>();
        oShopCommodityList.forEach(item->{
            oShopCommodityMap.put(item.getId(),item);
        });
        Map<String,List<ShopCommoditySpecs>> oShopCommoditySpecsMap = new HashMap<>();
        oShopCommoditySpecsList.forEach(item->{
            List<ShopCommoditySpecs> oShopCommoditySpecsMapList = new ArrayList<>();
            if(oShopCommoditySpecsMap.containsKey(item.getCommodityId())){
                oShopCommoditySpecsMapList = oShopCommoditySpecsMap.get(item.getCommodityId());
            }
            oShopCommoditySpecsMapList.add(item);
            oShopCommoditySpecsMap.put(item.getCommodityId(),oShopCommoditySpecsMapList);
        });
        //计算价格
        for(OrderTakeawayCommodityDto carOrderTakeawayCommodityDto : carOrderTakeawayCommodityDtoList){
            //判断商品是否是平台推荐商品,是平台推荐商品直接计算推荐价
            if(oShopCommodityMap.get(carOrderTakeawayCommodityDto.getCommodityId()).getIsSystemRecommend() == 1){
                carOrderTakeawayCommodityDto.setPrice(carOrderTakeawayCommodityDto.getNumber() * oShopCommodityMap.get(carOrderTakeawayCommodityDto.getCommodityId()).getSystemRecommendPrice());
            }else{
                //判断用户是否是此店铺的储蓄会员
                if(isSave){
                    //判断商品是否有规格
                    if(oShopCommoditySpecsMap.containsKey(carOrderTakeawayCommodityDto.getCommodityId())){
                        Double price = 0.0;
                        for(ShopCommoditySpecs oShopCommoditySpecs : oShopCommoditySpecsMap.get(carOrderTakeawayCommodityDto.getCommodityId())){
                            price += oShopCommoditySpecs.getMemberPrice();
                        }
                        carOrderTakeawayCommodityDto.setPrice(price * carOrderTakeawayCommodityDto.getNumber());
                    }else{
                        //没有规格直接按照商品价格计算
                        carOrderTakeawayCommodityDto.setPrice(carOrderTakeawayCommodityDto.getNumber() * oShopCommodityMap.get(carOrderTakeawayCommodityDto.getCommodityId()).getMemberPrice());
                    }
                }else{
                    //判断商品是否有规格
                    if(oShopCommoditySpecsMap.containsKey(carOrderTakeawayCommodityDto.getCommodityId())){
                        Double price = 0.0;
                        for(ShopCommoditySpecs oShopCommoditySpecs : oShopCommoditySpecsMap.get(carOrderTakeawayCommodityDto.getCommodityId())){
                            price += oShopCommoditySpecs.getOriginalPrice();
                        }
                        carOrderTakeawayCommodityDto.setPrice(price * carOrderTakeawayCommodityDto.getNumber());
                    }else{
                        //没有规格直接按照商品价格计算
                        carOrderTakeawayCommodityDto.setPrice(carOrderTakeawayCommodityDto.getNumber() * oShopCommodityMap.get(carOrderTakeawayCommodityDto.getCommodityId()).getOriginalPrice());
                    }
                }
            }
        }
        return Result.ok(carOrderTakeawayCommodityDtoList);
    }

}
